﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace CoolCode 
{
    public interface IConverter<T>
    {
        T Serialize(object o);
        object Deserialize(T value, Type objectType);
    }

    public class StringConverter : IConverter<string>
    {
        private static Dictionary<Type, TypeConverter> converters = new Dictionary<Type, TypeConverter>();

        #region IConverter<string> Members

        public virtual string Serialize(object o)
        {
            if (o == null)
                return string.Empty;
            if (o is DateTime)
                return ((DateTime)o).ToString("yyyy-MM-dd hh:mm:ss.ffff");
            Type objectType = o.GetType();
            if (!converters.Keys.Contains(objectType))
            {
                converters.Add(objectType, TypeDescriptor.GetConverter(objectType));
            }
            string value = converters[objectType].ConvertToString(o);
            return value.ToString();

        }

        public virtual object Deserialize(string value, Type objectType)
        {
            if (!converters.Keys.Contains(objectType))
            {
                converters.Add(objectType, TypeDescriptor.GetConverter(objectType));
            }
            object o = converters[objectType].ConvertFromString(value);
            return o;
        }

        #endregion
    }


    public class ConverterFactory
    {
        private static Dictionary<Type, object> converters = new Dictionary<Type, object>();

        public static IConverter<T> Build<T>()
        {
            var t = typeof(T);
            if (converters.Keys.Contains(t))
                return converters[t] as IConverter<T>;
            IConverter<T> converter = null;
            if (t == typeof(string))
                converter = new StringConverter() as IConverter<T>;
            if (converter == null)
                throw new NotImplementedException();
            converters.Add(t, converter);
            return converter;
        }



    }
}
